﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using WickedFlame.Core.Shapes;

namespace WickedFlame.Core.Layers
{
	public abstract class Layer : Control/*ContentControl*/, IDisposable
    {
        public Layer()
            : base()
        {
            _shapeList = new ShapeList(this);
            this.SizeChanged += new SizeChangedEventHandler(OnSizeChanged);
        }

        public void Dispose()
        {
            while (ShapeList.Count > 0)
            {
                this.ShapeList.RemoveAt(0);
            }
        }

        protected override Size ArrangeOverride(Size arrangeBounds)
        {
            return arrangeBounds;
        }

        protected override Size MeasureOverride(Size constraint)
        {
            // take all the space that is given by the parent
            return new Size(0, 0);
        }

        bool isSelecteable = true;
        public bool IsSelecteable
        {
            get
            {
                return isSelecteable;
            }
            set
            {
                isSelecteable = value;
                if (ShapeList != null)
                    foreach (DrawableShape shape in ShapeList)
                        shape.IsSelecteable = isSelecteable;
            }
        }
        
        ShapeList _shapeList;
        /// <summary>
        /// List of shapes that are on the canvas
        /// </summary>
        public ShapeList ShapeList
        {
            get
            {
                return _shapeList;
            }
            set
            {
                _shapeList = value;
            }
        }

        protected override int VisualChildrenCount
        {
            get 
            { 
                return ShapeList.Count; 
            }
        }


        /// <summary>
        /// Provide a required override for the GetVisualChild method
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        protected override Visual GetVisualChild(int index)
        {
            if (index < 0 || index > ShapeList.Count)
            {
                throw new ArgumentOutOfRangeException();
            }
            return (Visual)ShapeList[index];
        }

        /// <summary>
        /// Replace shape specified shape.
        /// Retruns false if failed to repalce
        /// </summary>
        /// <param name="originalShape"></param>
        /// <param name="newShape"></param>
        /// <returns></returns>
        public bool Replace(VectorShape originalShape, VectorShape newShape)
        {
            return ShapeList.Replace(originalShape, newShape);;
        }

        public virtual void AddShape(DrawableShape shape)
        {
            ShapeList.Add(shape);
        }

        private void OnSizeChanged(object sender, SizeChangedEventArgs e)
        {
            SetClipSize();
        }

        public virtual void SetClipSize()
        {
            this.Clip = new System.Windows.Media.RectangleGeometry(new System.Windows.Rect(0, 0, this.Width, this.Height));
        }

        public virtual void RemoveShape(VectorShape shape)
        {
            ShapeList.Remove(shape);
        }

        public void SelectShapes(Rect rectangle)
        {
            ShapeList.SelectShapes(rectangle);
        }

        public void UnselectAll()
        {
            ShapeList.UnselectAll();
        }

        /// <summary>
        /// Refreshes all shapes
        /// </summary>
        public void Refresh()
        {
            SetClipSize();
            foreach (VectorShape shape in ShapeList)
            {
                shape.Invalidate();
            }
        }
    }

    public class ShapeChangedEventArgs : EventArgs
    {
        DrawableShape changedshape;

        public ShapeChangedEventArgs(DrawableShape changedshape)
        {
            this.changedshape = changedshape;
        }

        public DrawableShape ChangedShape
        {
            get
            {
                return changedshape;
            }
        }
    }
}
